package cn.boodqian.airdata;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.*;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

@SuppressWarnings("serial")
public class AirdataServlet extends HttpServlet {
    public final static String[][] locationMappingData = {
        {"Shanghai/201", "Shanghai/pt"}, {"Shanghai/209", "Shanghai/ypsp"},
        {"Shanghai/185", "Shanghai/swc"}, {"Shanghai/215", "Shanghai/hk"},
        {"Shanghai/183", "Shanghai/jajcz"}, {"Shanghai/207", "Shanghai/xhssd"},
        {"Shanghai/193", "Shanghai/pdcs"}, {"Shanghai/195", "Shanghai/pdzj"},
        {"Shanghai/228", "Shanghai/pdxqjcz"}, {"Shanghai/203", "Shanghai/qpdsh"},
        {"Shanghai/999", "Shanghai/average"},
    };
    public final static HashMap<String, String> locationMappingMap;
    
    static {
        locationMappingMap = new HashMap<String, String>();
        for( String[] mapping : locationMappingData ) {
            locationMappingMap.put(mapping[0], mapping[1]);
        }
    }
    
	private final static Logger Log = Logger.getLogger(AirdataServlet.class.getName());
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		resp.setContentType("text/plain");
		resp.setCharacterEncoding("UTF-8");
		
		String path = req.getPathInfo();
		Log.info(path);
		String [] nodes = path.split("/");
		if( nodes.length < 3 ) {
			resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
			return;
		}
		
		String city = nodes[1];
		String location = nodes[2];
		int hour = 24;

		Map map = req.getParameterMap();
		if(map.containsKey("hour")) {
			hour = Integer.parseInt(req.getParameter("hour"));

			if(hour > AirData.MAX_HOURS || hour < 0)
				hour = AirData.MAX_HOURS;
		}
		
		AirData data = new AirData();

		// Mapping old Shanghai locations to CNEMC ones
		String locId = city+"/"+location;
		String newLocId = locId;
		if( locationMappingMap.containsKey(locId) )
			newLocId = locationMappingMap.get(locId);
			
		data = AirdataCache.getAirdataFromCache(newLocId, Calendar.HOUR_OF_DAY, hour);

		//			Calendar cal = Calendar.getInstance();
		//			cal.setTime(data.getTime());
		//			cal.add(Calendar.HOUR_OF_DAY, 8-cal.getTimeZone().getOffset(cal.getTime().getTime())/1000/3600); // To GMT+8 manually...
		//			data.setTime(cal.getTime());

		Gson gson = new GsonBuilder().setDateFormat("yyyy/MM/dd HH:mm:ss Z").create();
		//Gson gson = new Gson();
		String ret = gson.toJson(data);
		resp.getWriter().println(ret);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		StringBuilder builder = new StringBuilder();
		BufferedReader reader = new BufferedReader(new InputStreamReader(req.getInputStream()));
		String line;
		while ((line = reader.readLine()) != null) {
			builder.append(line);
		}
		String queryListJson = builder.toString();
		Gson gson = new GsonBuilder().setDateFormat("yyyy/MM/dd HH:mm:ss Z").create();
		Type listType = new TypeToken<ArrayList<HashMap<String,String>>>(){}.getType();
		ArrayList<HashMap<String,String>> queryList = gson.fromJson(queryListJson, listType);
		
		Boolean containsDayMonth = null;
		HashMap<String, AirData> airdataMap = new HashMap<String, AirData>();
		HashMap<String, HashMap<String, AirData>> airdataMap_v2 = new HashMap();
		for( HashMap<String, String> query : queryList ) {
			String locId = query.get("id");
			String hourStr = query.get("hour");
			String dayStr = query.get("day");
			String monthStr = query.get("month");
			if( locId == null ) continue;
			int hour = 24;
			int day = 30;
			int month = 12;
			try {
				if( hourStr != null )
					hour = Integer.parseInt(hourStr);
				if( dayStr != null )
				    day = Integer.parseInt(dayStr);
				if( monthStr != null )
				    month = Integer.parseInt(monthStr);
			} catch (NumberFormatException e ) {
				// do nothing
			}
			
			// Mapping old Shanghai locations to CNEMC ones
			String newLocId = locId;
			if( locationMappingMap.containsKey(locId) )
			    newLocId = locationMappingMap.get(locId);
			
			// Determine containsDayMonth in the first iteration
			if( containsDayMonth == null ) {
			    if( dayStr == null && monthStr == null )
			        containsDayMonth = false;
			    else
			        containsDayMonth = true;
			}
			
			if( !containsDayMonth ) {
			    // Old version, contains only hourly data
			    AirData airdata = AirdataCache.getAirdataFromCache(newLocId, Calendar.HOUR_OF_DAY, hour);
			    airdataMap.put(locId, airdata);
			} else {
			    // New version, contains hourly, daily and monthly data
			    airdataMap = new HashMap<String, AirData>();
			    AirData airdata = AirdataCache.getAirdataFromCache(newLocId, Calendar.HOUR_OF_DAY, hour);
			    airdataMap.put("hour", airdata);
			    airdata = AirdataCache.getAirdataFromCache(newLocId, Calendar.DAY_OF_MONTH, day);
			    airdataMap.put("day", airdata);
			    airdata = AirdataCache.getAirdataFromCache(newLocId, Calendar.MONTH, month);
			    airdataMap.put("month", airdata);
			    airdataMap_v2.put(locId, airdataMap);
			}
		}
		
		String ret = null;
		if( !containsDayMonth ) {
		    ret = gson.toJson(airdataMap);
		} else {
		    ret = gson.toJson(airdataMap_v2);
		}
		resp.setContentType("text/plain");
		resp.setCharacterEncoding("UTF-8");
		resp.getWriter().println(ret);
	}
}
